<template>
  <div id="go2-table-chart">
    <!-- 表格工具栏 -->
    <div class="go2-table-tool">
      <!-- 自定义工具栏 -->
      <div class="go2-table-prev">
        <a-checkbox-group
          v-model:value="showItems"
          :options="[
            { label: t('chart'), value: 'chart' },
            { label: t('table'), value: 'table' },
          ]"
        />
        <template :key="index" v-for="(item, index) in toolbar">
          <!-- 更多按钮 -->
          <go2-authority
            :value="item.code ? item.code : false"
            v-if="item.children && item.children.length > 0"
          >
            <a-dropdown>
              <a-button @click="item.event(selectedRowKeys)">
                {{ t(item.label) }}
              </a-button>
              <template #overlay>
                <a-menu>
                  <!-- 遍历子集 -->
                  <go2-authority
                    v-for="(child, i) in item.children"
                    :key="i"
                    :value="child.code ? item.code : false"
                  >
                    <a-menu-item>
                      <a @click="child.event(selectedRowKeys)">
                        {{ t(child.label) }}
                      </a>
                    </a-menu-item>
                  </go2-authority>
                </a-menu>
              </template>
            </a-dropdown>
          </go2-authority>
          <go2-authority :value="item.code ? item.code : false" v-else>
            <a-button
              :type="index == 0 ? 'primary' : 'default'"
              @click="item.event(selectedRowKeys)"
            >
              {{ t(item.label) }}
            </a-button>
          </go2-authority>
        </template>
      </div>
      <!-- 默认工具栏 -->
      <div class="go2-table-next" v-if="defaultToolbar">
        <!-- 刷新工具栏 -->
        <a-button @click="reload">
          <template #icon><SyncOutlined /></template>
        </a-button>
        <a-button @click="print">
          <template #icon><PrinterOutlined /></template>
        </a-button>
        <a-button @click="excel">
          <template #icon><file-excel-outlined /></template>
        </a-button>
      </div>
    </div>
    <div v-if="showItems.indexOf('chart') > -1">
      <chartlinebar 
        :fontSize="12"
        :width="'100%'" 
        :isStack="true"
        :autosize="false"
        :titleName="''"
        :xAxisData="xAxisData"
        :legendData="legendData"
        :seriesData="seriesData"
        @imgurl="setimgurl"
      />
    </div>

    <!-- 表格组件 -->
    <a-table
      v-if="showItems.indexOf('table') > -1"
      :rowKey="rowKey"
      @change="fetchData"
      :columns="columns"
      :loading="loading"
      :pagination="pagination"
      :dataSource="datasource"
      :row-selection="rowSelection"
      :size="size"
    >
      <template #headerCell="{ column }">
        <span>
          {{ column.title ? column.title : t(column.dataIndex) }}
        </span>
      </template>

      <!-- 列转换 -->
      <template :key="index" #bodyCell="{ column, record }">
        <!-- 行操作 -->
        <span v-if="column.dataIndex == 'operate'">
          <template :key="i" v-for="(item, i) in operate">
            <!-- 下拉操作 -->
            <a-dropdown v-if="item.children && item.children.length > 0">
              <a> {{ t(item.label) }} </a>
              <template #overlay>
                <a-menu>
                  <!-- 遍历子集 -->
                  <go2-authority
                    v-for="(child, i) in item.children"
                    :key="i"
                    :value="child.code ? item.code : false"
                  >
                    <a-menu-item>
                      <a @click="child.event(selectedRowKeys)">
                        {{ t(child.label) }}
                      </a>
                    </a-menu-item>
                  </go2-authority>
                </a-menu>
              </template>
            </a-dropdown>
            <!-- 单个操作 -->
            <go2-authority :value="item.code ? item.code : false" v-else>
              <a @click="item.event(record)"> {{ t(item.label) }} </a>
              <a-divider type="vertical" v-if="i != operate.length - 1" />
            </go2-authority>
          </template>
        </span>

        <!-- 原样输出 -->
        <span v-else-if="record">
          {{ record[column.dataIndex] }}
        </span>
      </template>

      <!-- 内容插槽 -->
      <template v-for="name in slotsData" #[name]="{ record }">
        <slot :name="name" :record="record"></slot>
      </template>
    </a-table>
  </div>
</template>

<script>
 
import { jsPDF } from "jspdf";
import autoTable from "jspdf-autotable";
import { useI18n } from "vue-i18n";
import "./index.less";
import chartlinebar from "./chartlinebar.vue";
import { defineComponent, onMounted, reactive, toRefs, watch, ref } from "vue";
import {
  AppstoreOutlined,
  PrinterOutlined,
  SyncOutlined,
  UserOutlined,
  ColumnHeightOutlined,
} from "@ant-design/icons-vue";
import { getImgUrl } from "@/core/tools/common.js";
import { logo } from "@/core/api/module/common";
//import "@/assets/font/hansans-normal-normal.js";
import XLSX from "xlsx";

export default defineComponent({
  name: "go2-table-chart",
  components: {
    chartlinebar,
    ColumnHeightOutlined,
    AppstoreOutlined,
    PrinterOutlined,
    SyncOutlined,
    UserOutlined,
  },
  /// 数据来源
  props: {
    title: {
      type: String,
      default: "ems report",
    },
    rowKey: {
      type: String,
      default: "id",
    },
    /// 扩展参数
    param: {
      type: Object,
      default: {
        isInit: true,
      },
    },
    /// 数据来源
    fetch: {
      type: Function,
      required: false,
    },
    /// 数据解析
    columns: {
      type: Array,
      required: true,
    },
    /// 头工具栏
    toolbar: {
      type: Array,
    },
    defaultToolbar: {
      type: Boolean,
      default: true,
    },
    /// 行工具栏
    operate: {
      type: Array || Boolean,
      default: false,
    },
    /// 分页参数
    pagination: {
      type: [Object, Boolean],
      default: false,
    },
    rowSelection: {
      type: Object,
    },
    size: {
      type: String,
      default: "default",
    },
    realyPagination: {
      type: Boolean,
      default: true,
    },
  },
  setup(props) {
    const slotsData = ref([]);
    const { t } = useI18n();

    /// 状态共享
    const state = reactive({
      pagination: props.pagination == false ? false : props.pagination, // 分页
      datasource: [], // 数据源
      xAxisData: [],
      seriesData: [],
      legendData: [],
      pdfheader: [],
      loading: true, // 加载
      columns: props.columns, // 字段
      selectedRowKeys: [], // 选中项
      size: props.size, // 表格大小
      showItems: ["chart", "table"],
      chartHeight: "200px",
    });

    /// 选中回调
    const onSelectChange = (selectedRowKeys) => {
      state.selectedRowKeys = selectedRowKeys;
    }; 

    /// 数据请求
    const fetchData = async (pagination) => {
      //判断是否为假分页
      if (props.realyPagination || pagination == undefined) {
        /// 开启加载
        state.loading = true;
        /// 请求数据
        let datapost = Object.assign(
          {},
          state.pagination,
          pagination,
          props.param
        );
        delete datapost.isInit;
        const { total, current, data } = await props.fetch(datapost);
        /// 状态重置
        if (state.pagination != false) {
          state.pagination.total = total;
          state.pagination.current = current;
          if (pagination != undefined) {
            state.pagination.pageSize = pagination.pageSize;
          }
        }
        state.datasource = data;
        //处理charts
        state.legendData = [];
        state.xAxisData = [];
        state.seriesData = [];
        state.pdfheader = [];
        if (state.columns.length > 0) {
          state.columns.forEach((x) => {
            if (x.dataIndex != "timestamp") {
              state.seriesData[x.dataIndex] = [];
              state.legendData.push({
                name: x.title,
                key: x.dataIndex,
              });
            }

            state.pdfheader.push({
              header: x.title,
              dataKey: x.dataIndex,
            });
          }); 
          data.forEach((item, index) => {
            for (let i in item) {
              if (i == "timestamp") {
                state.xAxisData.push(item[i]);
              } else {
                state.seriesData[i][index] = item[i];
              }
            }
          });
        }

        state.loading = false;
      } else {
        state.pagination.pageSize = pagination.pageSize;
      }
    };

    /// 刷新方法
    const reload = function () {
      fetchData();
    };

    /// 初始数据
    onMounted(async () => { 
    
      if (props.param.isInit !== false) {
        await fetchData();
      } else {
        state.loading = false;
      }
    });

    /// 监听扩展参数, 触发表格刷新
    watch(
      () => props.param,
      () => {
        fetchData();
      },
      { deep: true }
    );

    //监听列变化
    watch(
      () => props.columns,
      () => {
        state.columns = props.columns;
      }
    );

    /// 改变按钮尺寸
    const changeSize = (target) => {
      state.size = target;
    };

    let chartsimgurl = null;
    const setimgurl = (e) => {
      chartsimgurl = e;
    };

    /// 表格打印  
    const print = async () => {

    

      const PageMargin = { top: 20, right: 10, bottom: 15, left: 10 };
      const doc = new jsPDF({
        orientation: "p",
        unit: "mm",
        format: "a4",
      });

      //doc.setFont("hansans-normal");
      const pageWidth = doc.internal.pageSize.width; //总宽度
      doc.setFontSize(10); //Optional
      const PageConWidth = pageWidth - PageMargin.left - PageMargin.right; //内容宽度
      //设置图片
      if (state.showItems.indexOf("chart") > -1) {
        doc.addImage(
          chartsimgurl,
          "png",
          PageMargin.left,
          40,
          PageConWidth,
          PageConWidth * 0.7,
          undefined,
          "FAST"
        );
      }

      if (state.showItems.indexOf("table") > -1) {
        let startY = null;
        if (state.showItems.indexOf("chart") > -1) {
          startY = 200;
        }
        autoTable(doc,{
         // styles: { font: "hansans-normal" },
          columnStyles: { europe: { halign: "center" } }, // European countries centered
          body: state.datasource,
          columns: state.pdfheader,
          startY: startY, //第一次
          margin: PageMargin,
        });
      }

      const pages = doc.internal.getNumberOfPages();
      const pageHeight = doc.internal.pageSize.height; //Optional

      //获取logo
      const { data: logobase64, info } = await logo({});
      const logoH = 10;
      const logoW = (info[0] / info[1]) * logoH;

      for (let j = 1; j < pages + 1; j++) {
        let horizontalPos = pageWidth / 2; //Can be fixed number
        let verticalPos = pageHeight - 10; //Can be fixed number
        doc.setPage(j);
        doc.text(`${j} / ${pages}`, horizontalPos, verticalPos, {
          align: "center",
        });
        doc.setTextColor(105, 105, 105); //文字颜色
        doc.setDrawColor(105, 105, 105); // draw red lines
        doc.text(t("能源管理报表"), pageWidth - PageMargin.right, 10, {
          align: "right",
        }); //文字
        doc.addImage(logobase64, "PNG", PageMargin.left, 2.5, logoW, logoH); //logo
        //页眉的线
        doc.line(
          PageMargin.left,
          PageMargin.top - 5,
          pageWidth - PageMargin.right,
          PageMargin.top - 5
        );

        // doc.line(PageMargin.left, pageHeight - PageMargin.bottom + 5 , pageWidth - PageMargin.right, pageHeight - PageMargin.bottom + 5);  //页眉的线
      }

      //  doc.save("table.pdf"); //下载
      doc.autoPrint(); //自动打印
      doc.output("dataurlnewwindow", "打印");
    };

    const excel = async () => { 
      let linetitle = state.columns.map((colum)=>{ return colum.title}) ;
      let exceldata = [] ;
      exceldata.push(linetitle) ;
      state.datasource.forEach((dataitem)=>{
          let linedata = [] ;
           state.columns.forEach((colum)=>{
             linedata.push(dataitem[colum.dataIndex])
           })
        exceldata.push(linedata)
      })
      
      const worksheet = XLSX.utils.aoa_to_sheet(exceldata);  //array
     // const worksheet = XLSX.utils.json_to_sheet(state.datasource); //json
      const new_workbook = XLSX.utils.book_new();
      XLSX.utils.book_append_sheet(new_workbook, worksheet, props.title);
      // XLSX.utils.sheet_add_json(sheet1,data2);//替换
      XLSX.writeFile(new_workbook, props.title+'.xlsx'); // 保存的文件名
    };

    return {
      t, 
      setimgurl,
      /// 数据信息
      ...toRefs(state),
      /// 数据加载
      fetchData,
      /// 刷新方法
      reload,
      /// 选中字段
      onSelectChange,
      /// 改变大小
      changeSize,
      /// 打印
      print,
      excel,
      slotsData,
    };
  },
});
</script>